
local config = require 'config'
local alien = require 'alien'
local glib_g = require 'bindings.libglib'



module(...)


local guint = "uint"
local gint = "int"
local gulong = "ulong"
local gboolean = "int"

local GType = "pointer"

local GtkWindowType = 'int'
WINDOW_TOPLEVEL = 0 
WINDOW_POPUP = 1

local GtkDialogFlags = 'int'
DIALOG_MODAL = 1
DIALOG_DESTROY_WITH_PARENT = 2
DIALOG_NO_SEPARATOR = 4

local GtkButtonsType = 'int'
BUTTONS_NONE = 0
BUTTONS_OK = 1
BUTTONS_CLOSE = 2
BUTTONS_CANCEL = 3
BUTTONS_YES_NO = 4
BUTTONS_OK_CANCEL = 5

local GtkMessageType = 'int'
MESSAGE_INFO = 0
MESSAGE_WARNING = 1
MESSAGE_QUESTION = 2
MESSAGE_ERROR = 3
MESSAGE_OTHER = 4

RESPONSE_NONE = -1
RESPONSE_REJECT = -2
RESPONSE_ACCEPT = -3
RESPONSE_DELETE_EVENT = -4
RESPONSE_OK     = -5
RESPONSE_CANCEL = -6
RESPONSE_CLOSE  = -7
RESPONSE_YES    = -8
RESPONSE_NO     = -9
RESPONSE_APPLY  = -10
RESPONSE_HELP   = -11

GtkFileChooserAction = 'int'
FILE_CHOOSER_ACTION_OPEN = 0
FILE_CHOOSER_ACTION_SAVE = 1
FILE_CHOOSER_ACTION_SELECT_FOLDER = 2
FILE_CHOOSER_ACTION_CREATE_FOLDER = 3

local lib = alien.load(config.libgtk_path)

local function Func(name, types)
  local func = lib["gtk_"..name]
  func:types(types)
  _M[name] = func
end

Widget = alien.defstruct{
  {"object_parent_instance_g_type_instance_g_class", "pointer"};
  {"object_parent_instance_ref_count", "uint"};
  {"object_parent_instance_qdata", "pointer"};
  {"object_flags", "uint"};
  {"private_flags", "ushort"};
  {"state", "char"};
  {"saved_state", "char"};
  {"name", "pointer"};
  {"style", "pointer"};
  {"requisition_width", "int"};
  {"requisition_height", "int"};
  {"allocation_x", "int"};
  {"allocation_y", "int"};
  {"allocation_width", "int"};
  {"allocation_height", "int"};
  {"window", "pointer"};
  {"parent", "pointer"};
}

Func("init", { ret="void"; "pointer" --[[int *argc]], "pointer" --[[char*** argv]] })

Func("window_new", { ret="pointer" --[[GtkWidget*]]; GtkWindowType })

Func("container_set_border_width", { ret="void"; "pointer" --[[GtkContainer*]], guint --[[border_width]] })

Func("container_get_type", { ret=GType; })

Func("widget_realize", { ret="void"; "pointer" --[[GtkWidget*]] })

Func("window_fullscreen", { ret="void"; "pointer" --[[GtkWindow*]] })

Func("button_new_with_label", { ret="pointer" --[[GtkWidget*]]; "string" })

Func("container_add", { ret="void"; "pointer" --[[GtkContainer*]], "pointer" --[[GtkWidget*]] })

Func("widget_show_all", { ret="void"; "pointer" --[[GtkWidget*]] })

Func("main", { ret="void" })
Func("main_iteration", { ret=gboolean })
Func("main_iteration_do", { ret=gboolean; gboolean --[[blocking]] })

Func("dialog_new", { ret="pointer" --[[GtkWidget*]] })

Func("dialog_set_default_response", { ret="void"; "pointer" --[[GtkDialog*]], gint --[[response_id]] })

Func("rc_get_theme_dir", { ret="string" })
Func("rc_get_module_dir", { ret="string" })

Func("message_dialog_new", { ret="pointer" --[[GtkWidget*]];
  "pointer" --[[GtkWindow* parent]], GtkDialogFlags, GtkMessageType, GtkButtonsType, "string" })

Func("message_dialog_format_secondary_text", { ret="void"; "pointer" --[[GtkMessageDialog*]], "string" --[[message_format]] })  

Func("dialog_run", { ret=gint; "pointer" --[[GtkDialog*]] })

Func("widget_destroy", { ret="void"; "pointer" --[[GtkWidget*]] })

Func("rc_get_default_files", { ret="pointer" --[[gchar**]] })
Func("rc_add_default_file", { ret="void"; "string" --[[filename]] })

Func("main_quit", { ret="void" })

Func("file_chooser_dialog_new", { ret="pointer" --[[GtkWidget*]];
  "string" --[[title]], "pointer" --[[GtkWindow* parent]], GtkFileChooserAction, "string" --[[first_button_text]] })

local _file_chooser_get_filename_utf8 = lib["gtk_file_chooser_get_filename_utf8"]
_file_chooser_get_filename_utf8:types{ ret="pointer" --[[char*, must be freed]]; "pointer" --[[GtkFileChooser*]] }

function file_chooser_get_filename_utf8(...)
  local result = _file_chooser_get_filename_utf8(...)
  if result then
    local str = alien.buffer(result):tostring()
    glib_g.free(result)
    result = str
  end
  return result
end

Func("dialog_add_button", { ret="pointer" --[[GtkWidget*]]; "pointer" --[[GtkDialog*]], "string" --[[button_text]], gint --[[response_id]] })

user_function_types = { ret=gboolean; "pointer" --[[GtkWidget*]], "pointer" --[[GdkEvent*]], "pointer" --[[user_data]] }

Func("widget_set_events", { ret="void"; "pointer" --[[GtkWidget*]], gint --[[events]] })
Func("widget_add_events", { ret="void"; "pointer" --[[GtkWidget*]], gint --[[events]] })

Func("widget_set_app_paintable", { ret="void"; "pointer" --[[GtkWidget*]], gboolean --[[app_paintable]] })

Func("window_set_title", { ret="void"; "pointer" --[[GtkWindow*]], "string" })
Func("window_get_title", { ret="string"; "pointer" --[[GtkWindow*]] })

Func("drawing_area_new", { ret="pointer" --[[GtkWidget*]] })

Func("grab_add", { ret="void"; "pointer" --[[GtkWidget*]] })
Func("grab_remove", { ret="void"; "pointer" --[[GtkWidget*]] })

Func("widget_get_screen", { ret="pointer" --[[GdkScreen*]]; "pointer" --[[GtkWidget*]] })
Func("widget_get_pointer", { ret="void"; "pointer" --[[GtkWidget*]], "ref int" --[[x]], "ref int" --[[y]] })

Func("widget_set_size_request", { ret="void"; "pointer" --[[GtkWidget*]], "int" --[[width]], "int" --[[height]] })

Func("file_filter_new", {ret="pointer" --[[GtkFileFilter*]] })
Func("file_filter_set_name", { ret="void"; "pointer" --[[GtkFileFilter*]], "string" })
Func("file_filter_add_pattern", { ret="void"; "pointer" --[[GtkFileFilter*]], "string" })
Func("file_chooser_add_filter", { ret="void"; "pointer" --[[GtkFileChooser*]], "pointer" --[[GtkFileFilter*]] })
